﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace BJoin.Common
{
    public static class EnumHelper
    {
        /// <summary>
        /// 获取枚举值上的Description特性的说明
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="obj">枚举值</param>
        /// <returns>特性的说明</returns>
        public static string GetEnumDescription<T>(T obj)
        {
            if (obj == null) return string.Empty;
            var type = obj.GetType();
            var field = type.GetField(Enum.GetName(type, obj));
            var attr = field.GetCustomAttribute<DescriptionAttribute>();

            return attr?.Description ?? string.Empty;
        }

        public static TAttr GetEnumAttribute<TEnum, TAttr>(TEnum obj) where TAttr : Attribute
        {
            if (obj == null) return null;
            var type = obj.GetType();
            var field = type.GetField(Enum.GetName(type, obj));
            var attr = field.GetCustomAttribute<TAttr>();
            //
            return attr;
        }


        /// <summary>
        /// 将指定枚举类型转换成List，用来绑定DropDownList
        /// </summary>
        /// <typeparam name="T">枚举类型的基础型</typeparam>
        /// <param name="enumType">枚举类型</param>
        /// <param name="excludes">排除的枚举类型集合（基础型集合）</param>
        /// <param name="func">枚举类型对应的文字描述</param>
        /// <returns></returns>
        public static Dictionary<string, string> ConvertEnumToList<T>(Type enumType, IEnumerable<T> excludes = null, Func<T, string, string> func = null)
        {
            if (enumType.IsEnum == false) { return null; }
            var list = new Dictionary<string, string>();
            FieldInfo[] fields = enumType.GetFields();
            string strText = string.Empty;
            string strValue = string.Empty;
            T rawValue = default(T);
            foreach (FieldInfo field in fields)
            {
                if (!field.FieldType.IsEnum) continue;
                //strValue = Convert.ChangeType(enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null), typeof(T)).ToString();
                strValue = field.GetRawConstantValue().ToString();
                rawValue = (T)field.GetRawConstantValue();
                if (excludes != null && excludes.Any(o => o.Equals(rawValue)))
                {
                    continue;
                }
                if (func != null)
                {
                    strText = func(rawValue, "");
                }
                else
                {
                    Enum objEnum = Enum.Parse(enumType, field.Name) as Enum;
                    strText = GetEnumDescription(objEnum);
                }
                list.Add(strValue, strText);
            }
            return list;
        }
    }
    public class ReferenceEnumTypeAttribute : Attribute
    {
        public Type EnumType { get; set; }

        public ReferenceEnumTypeAttribute(Type enumType)
        {
            EnumType = enumType;
        }
    }
}
